/* 

问题 请描述vue响应式原理





_data 中的数据是元数据 也是 响应式的数据
vm身上的数据是代理数据 

数据代理
----------
我们配置好的的数据都在vm _data身上
因为this也好，插值也好 都是直接找vm对象，所以每次拿数据都要通过vm._data取拿
所以我们希望把_data的数据 在vm中放一份 我们读取修改 都是直接操作vm身上的数据
vm身上的数据被获取修改 时 会通知 _data中的数据变化

Object.keys()
返回一个有对象key组成的数组 有迭代器
for (let a of XX){
  for of 只能遍历具有迭代器对象的属性
}
let value of Object.values()
可以拿到对象的value值

for(let key of Object.keys()){

}

数据劫持
递归： 外部一个函数 内部 一个 函数 在内部函数内调用外部的函数 是递归
-------------
观察者模式
发布订阅模式
watch dep observe defineReactive

1把数据交给观察者函数
2遍历里所有属性给么每一个属性设置响应式






----------------------------

1封装Vue构造函数 参数是一个配置对象
在Vue构造函数中进行数据代理
数据代理
把options.data 中的数据放在Vue的实列的_data上
遍历所有的属性
Object.defineProperty(this,key,{
  get:function proxyGetter{
    return this._data[key] 
  },
  set:function proxyGetter(newVal){
    this._data[key] = newVal
  }
  //observer函数是为了判断需要被处理的响应式的类型 如果是·1基本数据类型 不进行响应式处理
  observe(this._data)
})

3封装一个observe函数
function observe(_data){
  //直接是一个基本类型值，不进行响应式处理
  if(typeof  _data !== "object" || _data ===null ) return

  //如果进入observe是一个对象类型，对这个对象的数据进行响应式处理
  new Observer(_data)

}
4 定义观察者类 就是发布 订阅 模型 中的发布者
 Class Observer{
  constructor(_data){
    this._data = _data
  }
  判断数据是一个对象还是数组，如果是对象，直接开始进行响应式操作
  如果是数组 遍历数组查看数组内部是不是有对象类型 进一步进行响应式处理

  判断是否是数组
  if（数组）{
    XXXX1
  }else{
    不是数组 是对象
    XXX2
  }
  数组处理方法XXX1
  遍历数据， 再次调用observe（遍历的item）函数

  对象处理方法XXXX2
  进行响应式处理
  再封装一个defineReactive函数(_data,key,_data[key]) ccc

  
}
5 封装响应式处理函数  defineReactive 函数
  function defineReactive(data,key,value){  ccc
    //递归调用 observe 传入 value 查看是否需要深层响应式

    //对当前的data中的key进行响应式操作
    //响应式处理
    Object.defineProperty(data,key,{
      
      get: function ReactiveGetter(){
        //只要Watcher（订阅者）来拿数据是，我们将叫数据放在（依赖）Dep中,Dep是一个数组保存当前数据的依赖项，还提供了Nosorty方法用来通知所有的watcher 
        console.log("在数据劫持中获取数据",value)
        return value
      },
      set:function ReactiveSetter(newVal){
        value = newVal
        console.log("在数据劫持中设置数据",newVal)
      }
    })
  }

  6.Dep就是发布订阅模型中的订阅器

  class Dep {
    
    constrctor{
      //每次实例化Dep就会创建一个空的数组,然后用来保存所有的watcher
      this.subs = []

    }
    //收集依赖
    depend(watcher){
      this.subs.push(watcher)
    }
    //通知watcher 要更新数据啦 赶紧调用方法
    notify(){
      this.subs.forEach(watcher){
        watcher.update()
      }
    }


  }




  7.封装Watcher类
  class Watcher {

    constructor(data,key){
      this.data = data
      this.key = key
      this.get()
    }
    
    get(){
      return this.data[this.key]
    }

    update(){
      console.log("有人修改值了，用在watcher更新数据")
    }


  }

































 */